package com.luhe.musicxml.annotion;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

//结点
@XmlNode(name = "node")
public class Node {

    //深度
    static int deep = 0;

    //子结点列表
    public List<Node> nodeList = new ArrayList<>();

    //加入结点
    public void add(Node node) {
        this.nodeList.add(node);
    }

    //生成XML格式
    public String toXML() {

        //空节点直接返回
        if (this == null) return "";

        //本层XML内容
        String r = "";
        try {
            //获取注明的结点名字
            Class<? extends Node> clazz = this.getClass();
            XmlNode annotation = clazz.getAnnotation(XmlNode.class);
            String name = annotation.name();
            String desc = annotation.desc();

            //获取注明的结点属性
            String attr = "";

            //获取注明结点的内容
            String text = "";

            //遍历字段
            Field[] fields = clazz.getFields();
            for (Field f : fields) {

                //是属性
                if (f.getAnnotation(XmlAttribute.class) != null) {
                    String value = String.valueOf(f.get(this));
                    String s = " %s='%s'";
                    if (value.length() != 0)
                        s = String.format(s, f.getName(), value);
                    attr = attr + s;
                }

                //是内容
                if (f.getAnnotation(XmlText.class) != null) {
                    text = String.valueOf(f.get(this));
                }

            }


            //构造xml
            if (text.length() == 0) {
                //有无子节点判断
                if (nodeList.size() != 0)
                    r = r + alignString(nTab(deep) + "<" + name + attr + ">", "<!-- " + desc + " -->", 100);
                if (nodeList.size() == 0)
                    r = r + alignString(nTab(deep) + "<" + name + attr + "/>", "<!-- " + desc + " -->", 100);
            }

            //根据是否有文本内容进行换行
            String newLine = (text.length() == 0 ? "\n" : "");

            //下一层结点
            for (Node n : nodeList) {
                //递归取下一层的xml结构
                deep = deep + 1;
                String nr = n.toXML();
                deep = deep - 1;
                r = r + newLine + nr;
            }
            //有内容结尾，换行
            if (text.length() != 0)
                r = r + newLine + alignString(nTab(deep) + "<" + name + attr + ">" + text + "</" + name + ">", "<!-- "+desc+" -->", 100);

            //不带内容结尾，不换行
            if (text.length() == 0 && nodeList.size() != 0)
                r = r + newLine + nTab(deep) + "</" + name + ">";

            //返回
            return r;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return r;
        }
    }

    //保存到文件
    public void toFile(String filePath) {
        File file=new File(filePath);

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(this.toXML().getBytes());
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private String nTab(int n) {
        String r = "";
        for (int i = 1; i <= n; i = i + 1) {
            r = r + "    ";
        }
        return r;
    }

    //打印文字，使len长度的文字进行两边对齐
    private String alignString(String left, String right, int len) {

        String r = "";
        int mid = len - left.length() - right.length();
        r = r + left;
        for (int i = 0; i <= mid; i = i + 1) {
            r = r + " ";
        }
        r = r + right;

        return r;
    }

    public static void main(String[] args) {
        Node node = new Node();
        System.out.println(node.toXML());
    }
}
